package jlib.component.clock
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.media.Sound;
	import flash.media.SoundChannel;

	public class TimeAlarm extends EventDispatcher
	{
		private var alarmTime:TimeObject;
		private var cloneAlarmTime:TimeObject;
		
		private var initPeriod:int;
		private var initMinute:int;
		
		private var period:int;
		private var periodMinute:int;
		
		private var dayCycle:int;
		private var currentTime:TimeObject;
		
		private var isRunnable:Boolean;
		
		private var _sound:Sound;
		private var soundLabel:String;
		private var soundChannel:SoundChannel;
		
		private var overTime:Boolean;
		
		public function TimeAlarm():void
		{
			enabled();
		}
		
		public function setCurrentTime(time:TimeObject): void { this.currentTime = time; }
		
		public function setAlarmTime(time:TimeObject, period:int=1, periodMinute:int=1, dayCycle:int=7, soundLabel:String='', sound:Sound=null): void
		{
			this.alarmTime = time;
			this.cloneAlarmTime = alarmTime.clone();
			this.period = initPeriod = period;
			this.periodMinute = periodMinute;
			this.dayCycle = dayCycle;
			this.soundLabel = soundLabel;
			this._sound = sound;
		}
		
		public function countDown(e:Event=null): void
		{
			if(isAlarm()) {
				period -= 1;
				if(period > 0) alarmTime.addMin(periodMinute);
				if(isRunnable){
					sound(true);
					this.dispatchEvent(new Event(Event.COMPLETE));
				}
			}
			if(hasNextDay()) nextDay();
		}
		
		private function nextDay(): void
		{
			switch(dayCycle){
				case 7: break;
				case 8 : 
					if(!alarmTime.isWeekend()){
						if(alarmTime.getDay() == 5){
							alarmTime.addDays(3);
							cloneAlarmTime.addDays(3);
						}else if(alarmTime.getDay() == 6){
							alarmTime.addDays(2);
							alarmTime.addDays(2);
						}else{
							alarmTime.addDays(1);
							cloneAlarmTime.addDays(1);
						}
						period = initPeriod;
						alarmTime.setDate(cloneAlarmTime.getNativeDate());
					}
				break;
				case 9 : 
					alarmTime.addDays(1);
					cloneAlarmTime.addDays(1);
					period = initPeriod;
					alarmTime.setDate(cloneAlarmTime.getNativeDate());
				break;
				default :
					alarmTime.addDays(7);
					cloneAlarmTime.addDays(7);
					period = initPeriod;
					alarmTime.setDate(cloneAlarmTime.getNativeDate());
				break;
			}
		}
		
		private function hasNextDay():Boolean { return (dayCycle != 7 && isTimeOver()); }
		private function isAlarm(): Boolean { return currentTime.equals(alarmTime) && (period > 0); }
		
		public function getSound(): Sound { return _sound;}
		public function setSound($sound:Sound): void { _sound = $sound; }
		public function getSoundLabel():String { return soundLabel; }
		
		public function getAlarmTime(): TimeObject { return alarmTime; }
		public function getDayCycle(): int { return dayCycle; }
		public function getPeriod(): int { return period; }
		public function getPeriodMinute(): int { return periodMinute; }
		
		public function isEnded(): Boolean { return (dayCycle == 7 && isTimeOver()); }
		
		public function enabled(): void { isRunnable = true; }
		public function disabled(): void { isRunnable = false; }
		
		public function sound($on:Boolean=true): void
		{
			if(!_sound|| !isRunnable) return ;
			if($on) soundChannel = _sound.play(0,20);
			else soundChannel.stop();
		}
		
		public function isTimeOver():Boolean
		{
			var result:Boolean = (alarmTime.getNativeDate().getTime() < currentTime.getNativeDate().getTime());
			return result;
		}
		
		public function toAlarmString(): String
		{
			var result:String = alarmTime.getUSClockTime()+' '+_parse(dayCycle)+' '+period+'회 '+periodMinute+'분 '+soundLabel;
			return result; 
		}
		
		public function toAllAlarmString(): String
		{
			var result:String = alarmTime.getYear()+'년 '+(alarmTime.getMonth()+1)+'월 '+alarmTime.getDate()+'일 '+alarmTime.getKoreanDay()+'요일 '+toAlarmString();
			return result;
		}
		
		public function toSaveString(): String
		{
			var result:String = alarmTime.getYear()+','+alarmTime.getMonth()+','+alarmTime.getDate()+','+alarmTime.getHour()+','+alarmTime.getMin()+','+period+','+periodMinute+','+dayCycle+','+soundLabel;
			return result;
		}
		
		public function equals($alarm:TimeAlarm): Boolean
		{
			return (this.toSaveString() == $alarm.toSaveString()); 
		}
		
		// Override 처리
		private function _parse(dayCycle:int): String
		{
			var result:String;
			switch(dayCycle){
				case 7 : result = '한번'; break;
				case 8 : result = '월~금'; break;
				case 9 : result = '매번';break;
			}
			return result;
		}
		
	}//c
}